package com.freewater.library.lending.checkedoutsheet.infrastructure.dao;

import com.freewater.library.lending.checkedoutsheet.model.CheckedOutRecord;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import org.apache.commons.lang3.Validate;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import java.util.List;
import java.util.Optional;

public class CheckedOutRecordDao extends SimpleJpaRepository<CheckedOutRecord, Long> {

    private final EntityManager entityManager;

    public CheckedOutRecordDao(EntityManager entityManager) {
        super(CheckedOutRecord.class, entityManager);
        this.entityManager = entityManager;
    }

    public boolean existsByUnique(CheckedOutRecord.Unique unique) {
        String hql = "select count(*) from CheckedOutRecord t where t.qrCode = :qrCode " +
                "and t.checkedOutBy = :checkedOutBy and t.checkedOutAt = :checkedOutAt ";
        Query query = this.entityManager.createQuery(hql, Long.class);
        query.setParameter("qrCode", unique.getQrCode());
        query.setParameter("checkedOutBy", unique.getCheckedOutBy());
        query.setParameter("checkedOutAt", unique.getCheckedOutAt());
        Long count = (Long) query.getSingleResult();
        return count != null && count > 0;
    }

    public Optional<CheckedOutRecord> findByUnique(CheckedOutRecord.Unique unique) {
        String hql = "from CheckedOutRecord t where t.qrCode = :qrCode " +
                "and t.checkedOutBy = :checkedOutBy and t.checkedOutAt = :checkedOutAt ";
        Query query = this.entityManager.createQuery(hql, CheckedOutRecord.class);
        query.setParameter("qrCode", unique.getQrCode());
        query.setParameter("checkedOutBy", unique.getCheckedOutBy());
        query.setParameter("checkedOutAt", unique.getCheckedOutAt());
        List<CheckedOutRecord> resultList = query.getResultList();
        Validate.isTrue(resultList.isEmpty() || resultList.size() == 1);
        return resultList.isEmpty() ? Optional.empty() : Optional.of(resultList.get(0));
    }
}
